package restlike.demo.shoreditchairways

import java.util.Random

import im.mange.shoreditch.api._
import im.mange.shoreditch.api.liftweb.ServiceHelper
import ServiceHelper._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import im.mange.shoreditch.api.liftweb.ServiceHelper

//TODO: pullout/rename etc
//TODO: see http://stackoverflow.com/questions/2863852/how-to-generate-a-random-string-in-java
object IdFactory {

  //TODO: store history and ensure unique
  def alphamumeric(size: Int) = {
    Generator.string("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", size)
  }

  def mumeric(size: Int) = {
    Generator.string("0123456789", size)
  }
}

//TODO: pullout/rename etc
object Generator {
  private val random = new Random()
  
  def string(characters: String, length: Int) = {
    val result = new Array[Char](length)
    var i = 0
    
    while (i < length) {
      result(i) = characters.charAt(random.nextInt(characters.length()))
      i = i + 1
    }

    new String(result)
  }
}

//http://localhost:4253/booking/metadata
object Booking extends ServiceHelper(base = "booking", version = "10001")(
  "create/reservation/" action CreateReservation,
  "make/payment/" action MakePayment,
  "choose/seat/" action ChooseSeat
)

case object CreateReservation extends Action {
  override val parameters = Parameters(List(In("to", None, Nil), In("from", None, Nil)), Some(Out("pnr")))

  override def run(in: List[In]) = {
    //TODO: use a future to sleep a bit
    val booking = Pnr(IdFactory.alphamumeric(6))

    Future {
      Thread.sleep(5000)
      DemoState.bookings = booking :: DemoState.bookings
    }

    //TODO: ultimately this wont be here obv ...
    Future {
      Thread.sleep(10000)
      booking.paymentConfirmed = true
    }

    //TODO: ultimately this wont be here obv ...
    Future {
      Thread.sleep(15000)
      booking.seatReserved = true
    }

    success(Some(booking.ref))
  }
}

case object MakePayment extends Action {
  override def run(in: List[In]) = success(None)
}

case object ChooseSeat extends Action {
  override def run(in: List[In]) = success(None)
}
